package com.united.ucts.modules.auth.service.impl;

import com.united.frame.common.constant.AuthConstant;
import com.united.frame.common.enums.AuthResultCodeEnum;
import com.united.frame.plugin.security.CurrUser;
import com.united.ucts.common.plugin.feign.AdminService;
import com.united.ucts.common.plugin.feign.PortalService;
import com.united.ucts.modules.auth.domain.MyUserDetails;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.authentication.CredentialsExpiredException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

/**
 * 用户管理业务类
 * 用于根据当前请求客户端以及登录用户获取该登录用户详情
 *
 * @author Hudan
 * @version 1.0
 * @filename MyUserDetailsService.java
 * @copyright <a href="www.united.cn">www.united.cn</a>
 * @date 2019-10-10
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class UserServiceImpl implements UserDetailsService {

    private final AdminService adminService;
    private final PortalService portalService;
    private final HttpServletRequest request;

    /**
     * 根据当前登录用户名/用户编号 获取该登录用户详情
     *
     * @param username 登录用户名/用户编号
     * @return 登录用户详情
     */
    @Override
    public UserDetails loadUserByUsername(String username) {
        // 获取当前请求 客户端信息 (目前用于判断是admin还是前端应用)
        String clientId = request.getParameter(AuthConstant.JWT_CLIENT_ID);

        // 获取当前登录用户详情
        CurrUser currUser;
        if (AuthConstant.ADMIN_CLIENT_ID.equals(clientId)) {
            currUser = adminService.loadUserByUsername(username);
        } else {
            currUser = portalService.loadUserByUsername(username);
        }

        if (Objects.isNull(currUser)) {
            throw new UsernameNotFoundException(AuthResultCodeEnum.USERNAME_OR_PASS_ERROR.getMessage());
        }

        currUser.setClientId(clientId);
        MyUserDetails myUserDetails = new MyUserDetails(currUser);
        if (!myUserDetails.isEnabled()) {
            throw new DisabledException(AuthResultCodeEnum.ACCOUNT_DISABLED.getMessage());
        } else if (!myUserDetails.isAccountNonLocked()) {
            throw new LockedException(AuthResultCodeEnum.ACCOUNT_LOCKED.getMessage());
        } else if (!myUserDetails.isAccountNonExpired()) {
            throw new AccountExpiredException(AuthResultCodeEnum.ACCOUNT_EXPIRED.getMessage());
        } else if (!myUserDetails.isCredentialsNonExpired()) {
            throw new CredentialsExpiredException(AuthResultCodeEnum.CREDENTIALS_EXPIRED.getMessage());
        }
        return myUserDetails;
    }
}